﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using EFMysql;
using CustomMVC;
using System.Diagnostics;
using CommonLib;
using System.Transactions;
using MySql.Data.MySqlClient;

namespace BLL
{
    public class UserBll:BaseBll
    {
        public Tuple<pre_user,int,List<pre_privileges>> Login(pre_user user)
        {
            List<Conditioner> condition = new List<Conditioner>();
            condition.Add(new Conditioner { Key = "username", Value = user.username, Contract = "=" });
            condition.Add(new Conditioner { Key = "password", Value = user.password, Contract = "=" });
            try
            {
                using (Model1 db = new Model1())
                {
                    var query = db.pre_user.AsQueryable();
                    int? userGroup = null;
                    List<pre_privileges> userPrivileges = new List<pre_privileges>();
                    List<pre_user> list = LinqHelperExtension.Where(query, condition.ToArray()).ToList();
                    if (list.Count > 0)
                    {
                        list[0].logip = user.logip;
                        list[0].logcount = list[0].logcount.HasValue ? list[0].logcount.Value + 1 : 1;
                        list[0].logtime = GeneralTools.ConvertDateTimeInt(DateTime.Now);
                        List<string> changeFields = new List<string>();
                        changeFields.Add("logip");
                        changeFields.Add("logcount");
                        changeFields.Add("logtime");                        
                        LinqHelper.Update(list[0], changeFields);
                        userGroup = GetUserGroup(list[0]);
                        userPrivileges = GetUserPrivileges(userGroup, null, null);
                        userPrivileges.AddRange(GetUserPrivileges(null, list[0].userid, null));
                        Tuple<pre_user, int, List<pre_privileges>> result = new Tuple<pre_user, int, List<pre_privileges>>(list[0], userGroup.Value, userPrivileges);
                        return result;
                    } 
                               
                    return null;
                }
            }
            catch(Exception ex)
            {
                Trace.WriteLine(DateTime.Now + ex.Message + "\n\r");              
                throw ex;
            }
        }

        public List<pre_user> GetAdmin()
        {
            try
            {              
                using (Model1 db = new Model1())
                {
                    List<pre_user> admin=db.pre_user.SqlQuery(@"SELECT t1.* FROM pre_user t1 INNER JOIN pre_group_user_rel t2 on t1.userid=t2.USERID
INNER JOIN pre_group t3 on t3.ID=t2.GROUPID WHERE t3.old_role=@admin", new MySqlParameter("@admin", FixGroup.admin.ToString())).ToList();

                    return admin;
                }
            }
            catch (Exception ex)
            {
                Trace.WriteLine(DateTime.Now + ex.Message + "\n\r");
                throw ex;
            }
        }

        public List<pre_group> GetGroup()
        {
            try
            {
                using (Model1 db = new Model1())
                {
                    var query = db.pre_group.AsQueryable();
                    List<pre_group> list = LinqHelperExtension.Where(query, new Conditioner[] { }).ToList();
                    return list.Count > 0 ? list : null;
                }
            }
            catch (Exception ex)
            {
                Trace.WriteLine(DateTime.Now + ex.Message + "\n\r");
                throw ex;
            }
        }

        public int? GetUserGroup(pre_user user)
        {
            List<Conditioner> condition = new List<Conditioner>();
            condition.Add(new Conditioner { Key = "USERID", Value = user.userid.ToString(), Contract = "=" });
            try
            {
                using (Model1 db = new Model1())
                {
                    var query = db.pre_group_user_rel.AsQueryable();
                    List<pre_group_user_rel> list = LinqHelperExtension.Where(query, condition.ToArray()).ToList();
                    return list.Count > 0 ? list[0].GROUPID : (int?)null;
                }
            }
            catch (Exception ex)
            {
                Trace.WriteLine(DateTime.Now + ex.Message+"\n\r");
                throw ex;
            }
        }

        public List<pre_privileges> GetUserPrivileges(int? groupId,long? userid,string funcId)
        {
            List<Conditioner> condition = new List<Conditioner>();
            if (groupId.HasValue) {
                condition.Add(new Conditioner { Key = "GROUPID", Value = groupId.Value.ToString(), Contract = "=" });
            }
            if (userid.HasValue)
            {
                condition.Add(new Conditioner { Key = "USERID", Value = userid.Value.ToString(), Contract = "=" });
            }
            if (!string.IsNullOrEmpty(funcId))
            {
                condition.Add(new Conditioner { Key = "FUNCID", Value = funcId, Contract = "=" });

            }
            try
            {
                using (Model1 db = new Model1())
                {
                    var query = db.pre_privileges.AsQueryable();
                    List<pre_privileges> list = LinqHelperExtension.Where(query, condition.ToArray()).ToList();
                    return list.Count > 0 ? list : null;
                }
            }
            catch (Exception ex)
            {
                Trace.WriteLine(DateTime.Now + ex.Message + "\n\r");
                throw ex;
            }
        }

        public pre_user GetUserBySessionID(string session)
        {
            try
            {
                List<Tuple<pre_user, string,int,List<pre_privileges>>> loginUser = WebVar<Tuple<pre_user, string,int,List<pre_privileges>>>.GetList;
                List<Tuple<pre_user, string, int, List<pre_privileges>>> user = loginUser.FindAll(o => o.Item2.ToString() == session);
                return user.Count > 0 ? user[0].Item1 : null;
            }
            catch (Exception ex)
            {
                Trace.WriteLine(DateTime.Now + ex.Message + "\n\r");             
                throw ex;
            }
        }

        public bool UserReg(pre_user user)
        {
            using (TransactionScope scope = new TransactionScope())
            {
                try
                {

                    LinqHelper.Add(user);
                    using (Model1 db = new Model1())
                    {
                        var query = db.pre_user.AsQueryable();
                        List<pre_user> regUser = LinqHelperExtension.Where(query, new Conditioner[] {
                            new Conditioner { Key = "username", Value = user.username, Contract = "=" },
                        new Conditioner {Key="password",Value=user.password,Contract="=" } }).ToList();
                        if (regUser.Count < 1)
                        {
                            scope.Dispose();
                            return false;
                        }
                        else
                        {
                            if (LinqHelper.Add(new pre_group_user_rel { GROUPID = 1, USERID = int.Parse(regUser[0].userid.Value.ToString()) }))
                            {
                                scope.Complete();
                                return true;                              
                            }
                            else
                            {
                                scope.Dispose();
                                return false;
                            }

                        }

                    }

                }
                catch (Exception ex)
                {
                    Trace.WriteLine(DateTime.Now + ex.Message + "\n\r");
                    scope.Dispose();
                    return false;
                }
            }
        }

        public void Logout(string session)
        {
            try
            {
                List<Tuple<pre_user, string, int, List<pre_privileges>>> loginUser = WebVar<Tuple<pre_user, string, int, List<pre_privileges>>>.GetList;
                List<Tuple<pre_user, string, int, List<pre_privileges>>> user = loginUser.FindAll(o => o.Item2.ToString() == session);
                if (user.Count > 0)
                {
                    loginUser.Remove(user[0]);
                }
            }
            catch (Exception ex)
            {
                Trace.WriteLine(DateTime.Now + ex.Message + "\n\r");              
                throw ex;
            }
        }

        public bool CheckLogin(string session)
        {
            try
            {
                List<Tuple<pre_user, string, int, List<pre_privileges>>> loginUser = WebVar<Tuple< pre_user, string, int, List<pre_privileges>>>.GetList;
                List<Tuple<pre_user, string, int, List<pre_privileges>>> user = loginUser.FindAll(o => o.Item2.ToString() == session);
                return user.Count > 0 ? true : false;
            }
            catch (Exception ex)
            {
                Trace.WriteLine(DateTime.Now + ex.Message + "\n\r");              
                throw ex;
            }
        }

        public bool ModPassword(string sessionID, string newPassword, string oldPassword)
        {
            List<Tuple<pre_user, string, int, List<pre_privileges>>> loginUsers = WebVar<Tuple<pre_user,string,int,List<pre_privileges>>>.GetList;
            Tuple<pre_user, string, int, List<pre_privileges>> user = loginUsers.Find(o => o.Item2 == sessionID && o.Item1.password == oldPassword);
            if (!Equals(user,null))
            {
                try
                {
                    user.Item1.password = newPassword;
                    if (LinqHelper.Update(user.Item1, new List<string> { "password" }))
                    {
                        user.Item1.password = newPassword;
                        return true;
                    }
                    else
                    {

                        return false;
                    }
                }catch(Exception ex)
                {
                    Trace.WriteLine(DateTime.Now + ex.Message + "\n\r");
                    throw ex;
                }
            }
            else
            {
                return false;
            }
        }
    }
}
